﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Xml;
using PPI.Entities.XML;
using PPI.General;
using VMind.Global;

namespace PPI.Client.Logic.XML
{
    public class LXmlOutbox 
    {
        protected EXmlOutboxBase m_EntityBase;
        protected XmlDocument m_XmlDocument;

        public LXmlOutbox(EXmlOutboxBase xmlOutboxEntity)
        {
            m_EntityBase = xmlOutboxEntity;
            SetupXml();
        }

        private void SetupXml()
        {
            m_XmlDocument = new XmlDocument();
            if (File.Exists(m_EntityBase.XmlFileName))
            {
                try
                {
                    m_XmlDocument.Load(m_EntityBase.XmlFileName);
                }
                catch (Exception ex)
                {
                    CreateBaseSchema();
                }

            }
            if (m_XmlDocument.ChildNodes.Count == 0)
            {
                CreateBaseSchema();
            }
            FillFoldersNode();
            m_XmlDocument.Save(m_EntityBase.XmlFileName);


        }

        private void CreateBaseSchema()
        {
            XmlNode _FoldersNode;
            XmlNode _DocumentNode = m_XmlDocument.CreateXmlDeclaration("1.0", "UTF-8", null);
            m_XmlDocument.AppendChild(_DocumentNode);

            _FoldersNode = m_XmlDocument.CreateElement("Folders");
            m_XmlDocument.AppendChild(_FoldersNode);
        }

        private void FillFoldersNode()
        {
            DirectoryInfo outboxDirectory = new DirectoryInfo(m_EntityBase.OutboxPath);
            DirectoryInfo[] outboxFolders = outboxDirectory.GetDirectories();
            XmlNode alredyFolderNode = null;
            XmlNode parentFolderNode = GetParentFolderNode();
            bool AddFolder = true;

            foreach (DirectoryInfo Folder in outboxFolders)
            {
                alredyFolderNode = m_XmlDocument.SelectSingleNode(@"Folders/Folder[@ID='" + Folder.Name + "']");
                if (alredyFolderNode == null)
                {
                    parentFolderNode.AppendChild(m_EntityBase.CreateNode(m_XmlDocument, Folder));
                }
            }
        }

        private XmlNode GetParentFolderNode()
        {
            return m_XmlDocument.ChildNodes[1];
        }

        public EXmlOutboxBase GetOutboxById(string idFolder)
        {
            XmlNode folderNode = m_XmlDocument.SelectSingleNode(@"//Folder[@ID='" + idFolder + "']");
            EXmlOutboxBase returnOutbox = (EXmlOutboxBase)m_EntityBase.Clone();

            returnOutbox.ConnectionString = folderNode["ConnectionString"].InnerText;
            returnOutbox.FullPath = folderNode["Path"].InnerText;
            returnOutbox.IsOpened = ConvertHelper.Tobool(folderNode["Open"].InnerText);
            returnOutbox.IsDataUploaded = ConvertHelper.Tobool(folderNode["Data_Uploaded"].InnerText);
            returnOutbox.IsImagesUploaded = ConvertHelper.Tobool(folderNode["Images_Uploaded"].InnerText);
            returnOutbox.DataFinishedToUpload = ConvertHelper.ToDateTime(folderNode["Data_Finished"].InnerText);
            returnOutbox.ImagesFinishedToUpload = ConvertHelper.ToDateTime(folderNode["Images_Finished"].InnerText);
            returnOutbox.Id = folderNode.Attributes["ID"].Value;
            return returnOutbox;
        }

        public void UpdateNode(EXmlOutboxBase outbox)
        {
            XmlNode folderNode = m_XmlDocument.SelectSingleNode(@"//Folder[@ID='" + outbox.Id + "']");
            folderNode["Open"].InnerText = outbox.IsOpened.ToString();
            folderNode["Data_Uploaded"].InnerText = outbox.IsDataUploaded.ToString();
            folderNode["Images_Uploaded"].InnerText = outbox.IsImagesUploaded.ToString();
            folderNode["Data_Finished"].InnerText = outbox.DataFinishedToUpload.ToString();
            folderNode["Images_Finished"].InnerText = outbox.ImagesFinishedToUpload.ToString();
            folderNode["Path"].InnerText = outbox.FullPath;
            folderNode["ConnectionString"].InnerText = outbox.ConnectionString;
            m_XmlDocument.Save(m_EntityBase.XmlFileName);
        }

        public List<EXmlOutboxBase> GetOutboxesToUploadData()
        {
            List<EXmlOutboxBase> returnOutboxList = new List<EXmlOutboxBase>();
            XmlNode parentFolderNode = GetParentFolderNode();
            foreach (XmlNode folderChild in parentFolderNode.ChildNodes)
            {
                EXmlOutboxBase tmpOutbox = GetOutboxById(folderChild.Attributes["ID"].Value);
                if (!tmpOutbox.IsDataUploaded && !returnOutboxList.Contains(tmpOutbox))
                    returnOutboxList.Add(tmpOutbox);
            }
            return returnOutboxList;
        }

        public List<EXmlOutboxBase> GetOutboxesToUploadImages()
        {
            List<EXmlOutboxBase> returnOutboxList = new List<EXmlOutboxBase>();
            XmlNode parentFolderNode = GetParentFolderNode();
            foreach (XmlNode folderChild in parentFolderNode.ChildNodes)
            {
                EXmlOutboxBase tmpOutbox = GetOutboxById(folderChild.Attributes["ID"].Value);
                if (tmpOutbox.IsDataUploaded && !returnOutboxList.Contains(tmpOutbox) && !tmpOutbox.IsImagesUploaded)
                    returnOutboxList.Add(tmpOutbox);
            }
            return returnOutboxList;
        }

        public List<EXmlOutboxBase> GetAll()
        {
            List<EXmlOutboxBase> returnOutboxList = new List<EXmlOutboxBase>();
            XmlNode parentFolderNode = GetParentFolderNode();
            foreach (XmlNode folderChild in parentFolderNode.ChildNodes)
            {
                EXmlOutboxBase tmpOutbox = GetOutboxById(folderChild.Attributes["ID"].Value);
                if (!returnOutboxList.Contains(tmpOutbox))
                    returnOutboxList.Add(tmpOutbox);
            }
            return returnOutboxList;
        }

        public List<EXmlOutboxBase> GetOutboxesToUpload()
        {
            List<EXmlOutboxBase> returnOutboxList = new List<EXmlOutboxBase>();
            XmlNode parentFolderNode = GetParentFolderNode();
            foreach (XmlNode folderChild in parentFolderNode.ChildNodes)
            {
                EXmlOutboxBase tmpOutbox = GetOutboxById(folderChild.Attributes["ID"].Value);
                if ((!tmpOutbox.IsDataUploaded || !tmpOutbox.IsImagesUploaded) && !returnOutboxList.Contains(tmpOutbox))
                    returnOutboxList.Add(tmpOutbox);
            }
            return returnOutboxList;
        }

        public void InsertNode(EXmlOutboxBase outbox, DirectoryInfo folder)
        {
            XmlNode parentFolderNode = GetParentFolderNode();
            parentFolderNode.AppendChild(outbox.CreateNode(m_XmlDocument, folder));
            m_XmlDocument.Save(m_EntityBase.XmlFileName);

        }

        public static List<EXmlOutboxBase> LoadAllOutboxes()
        {
            List<EXmlOutboxBase> _AllDatabases = new List<EXmlOutboxBase>();
            EXmlOutboxBase _GPSDatabase = new EXmlOutboxGPS();
            EXmlOutboxBase _InspectionDatabase = new EXmlOutboxInspection();
            EXmlOutboxBase _DistributionGPSDatabase = new EXmlOutboxDistributionGPS();
            EXmlOutboxBase _DistributionInspectionDatabase = new EXmlOutboxDistributionInspection();

            LXmlOutbox _Service = new LXmlOutbox(_GPSDatabase);
            _AllDatabases.AddRange(_Service.GetOutboxesToUpload());

            _Service = new LXmlOutbox(_InspectionDatabase);
            _AllDatabases.AddRange(_Service.GetOutboxesToUpload());

            _Service = new LXmlOutbox(_DistributionGPSDatabase);
            _AllDatabases.AddRange(_Service.GetOutboxesToUpload());

            _Service = new LXmlOutbox(_DistributionInspectionDatabase);
            _AllDatabases.AddRange(_Service.GetOutboxesToUpload());

            return _AllDatabases;
        }

        public void CopyToSentFolder()
        {
            string fullDestinationFolder= CopyToFolder(m_EntityBase.SentPath);
            if (!string.IsNullOrEmpty(fullDestinationFolder))
            {
                m_EntityBase.FullPath = fullDestinationFolder;
                m_EntityBase.ConnectionString = DirHelper.GetSdfPath(fullDestinationFolder);
                m_EntityBase.IsImagesUploaded = true;
                m_EntityBase.ImagesFinishedToUpload = DateTime.Now;
                UpdateNode(m_EntityBase);
            }

        }

        private string CopyToFolder(string destinationFolder)
        {
            try
            {
                DirectoryInfo SourceDirectory = new DirectoryInfo(m_EntityBase.FullPath);
                DirectoryInfo DestinationDirectory = new DirectoryInfo(destinationFolder + "//" + SourceDirectory.Name);

                if (!DestinationDirectory.Exists)
                    DestinationDirectory.Create();

                DirHelper.CopyFiles(SourceDirectory, DestinationDirectory, true);
                SourceDirectory.Delete(true);

                return DestinationDirectory.FullName;
            }catch(Exception ex)
            {
                return null;
            }
        }

    }
}
